#include <gtest/gtest.h>
#include "../../mqserver/virtualhost.hpp"

using arg = std::unordered_map<std::string, std::string>;
class HostTest : public testing::Test
{
public:
    virtual void SetUp() override
    {
        _host = std::make_shared<VirtualHost>("host1", "./data/host1/message", "./data/host1/host.db");
        _host->declareExchange("exchange1", ExchangeType::DIRECT, true, false, arg());
        _host->declareExchange("exchange2", ExchangeType::DIRECT, true, false, arg());
        _host->declareExchange("exchange3", ExchangeType::DIRECT, true, false, arg());
    
        _host->declareMsgQueue("queue1", true, false, false, arg());
        _host->declareMsgQueue("queue2", true, false, false, arg());
        _host->declareMsgQueue("queue3", true, false, false, arg());

        _host->bind("exchange1", "queue1", "news.music.dj");
        _host->bind("exchange1", "queue2", "news.music.pop");
        _host->bind("exchange1", "queue3", "news.music.lock");

        _host->bind("exchange2", "queue1", "news.music.dj");
        _host->bind("exchange2", "queue2", "news.music.pop");
        _host->bind("exchange2", "queue3", "news.music.lock");

        _host->bind("exchange3", "queue1", "news.music.dj");
        _host->bind("exchange3", "queue2", "news.music.pop");
        _host->bind("exchange3", "queue3", "news.music.lock");

        _host->basicPublish("queue1", nullptr, "hello-1");
        _host->basicPublish("queue1", nullptr, "hello-2");
        _host->basicPublish("queue1", nullptr, "hello-3");

        _host->basicPublish("queue2", nullptr, "hello-1");
        _host->basicPublish("queue2", nullptr, "hello-2");
        _host->basicPublish("queue2", nullptr, "hello-3");

        _host->basicPublish("queue3", nullptr, "hello-1");
        _host->basicPublish("queue3", nullptr, "hello-2");
        _host->basicPublish("queue3", nullptr, "hello-3");
    }
    virtual void TearDown() override
    {
        // _host->clear();
    }

public:
    VirtualHost::Ptr _host;
};

TEST_F(HostTest, init)
{

    ASSERT_EQ(_host->existsExchange("exchange1"), true);
    ASSERT_EQ(_host->existsExchange("exchange2"), true);
    ASSERT_EQ(_host->existsExchange("exchange3"), true);

    ASSERT_EQ(_host->existsMsgQueue("queue1"), true);
    ASSERT_EQ(_host->existsMsgQueue("queue2"), true);
    ASSERT_EQ(_host->existsMsgQueue("queue3"), true);

    ASSERT_EQ(_host->existsBinding("exchange1", "queue1"), true);
    ASSERT_EQ(_host->existsBinding("exchange1", "queue2"), true);
    ASSERT_EQ(_host->existsBinding("exchange1", "queue3"), true);

    ASSERT_EQ(_host->existsBinding("exchange2", "queue1"), true);
    ASSERT_EQ(_host->existsBinding("exchange2", "queue2"), true);
    ASSERT_EQ(_host->existsBinding("exchange2", "queue3"), true);

    ASSERT_EQ(_host->existsBinding("exchange3", "queue1"), true);
    ASSERT_EQ(_host->existsBinding("exchange3", "queue2"), true);
    ASSERT_EQ(_host->existsBinding("exchange3", "queue3"), true);

    // MessagePtr msg1 = _host->basicConsume("queue1");
    // EXPECT_EQ(msg1->paylode().body(), "hello-1");
    // MessagePtr msg2 = _host->basicConsume("queue1");
    // EXPECT_EQ(msg2->paylode().body(), "hello-2");
    // MessagePtr msg3 = _host->basicConsume("queue1");
    // EXPECT_EQ(msg3->paylode().body(), "hello-3");
    // MessagePtr msg4 = _host->basicConsume("queue1");
    // EXPECT_EQ(msg4.get(), nullptr);
}
TEST_F(HostTest, deleteExchange)
{
    _host->deleteExchange("exchange1");
    ASSERT_EQ(_host->existsBinding("exchange1", "queue1"), false);
    ASSERT_EQ(_host->existsBinding("exchange1", "queue2"), false);
    ASSERT_EQ(_host->existsBinding("exchange1", "queue3"), false);
}
TEST_F(HostTest, removeMsgQueue)
{
    _host->deleteMsgQueue("queue1");
    ASSERT_EQ(_host->existsBinding("exchange1", "queue1"), false);
    ASSERT_EQ(_host->existsBinding("exchange2", "queue1"), false);
    ASSERT_EQ(_host->existsBinding("exchange3", "queue1"), false);

    MessagePtr msg1 = _host->basicConsume("queue1");
    EXPECT_EQ(msg1.get(), nullptr);
}
TEST_F(HostTest, basicAck)
{
    MessagePtr msg1 = _host->basicConsume("queue1");
    EXPECT_EQ(msg1->paylode().body(), "hello-1");
    _host->basicAck("queue1", msg1->paylode().property().id());

    MessagePtr msg2 = _host->basicConsume("queue1");
    EXPECT_EQ(msg2->paylode().body(), "hello-2");
    _host->basicAck("queue1", msg2->paylode().property().id());

    MessagePtr msg3 = _host->basicConsume("queue1");
    EXPECT_EQ(msg3->paylode().body(), "hello-3");
    _host->basicAck("queue1", msg3->paylode().property().id());
}

int main(int argc, char* argv[])
{
    testing::InitGoogleTest(&argc, argv);       //函数名写第三遍，别忘了
    return RUN_ALL_TESTS();
}
